home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 142 / Gekkan Dennou Club - 2000.3 Vol. 142 (Japan).7z / Gekkan Dennou Club - 2000.3 Vol. 142 (Japan) (Track 1).bin / docs / s44poi / s44poi02.doc
Text File  |  2000-02-06  |  22KB  |  498 lines

  1. ────────────────────────────────────
  2.                  ~S44PLAY.Xのココがポイント~
  3.  
  4.                          2.FMPフォーマット
  5.  
  6.                                 鎌田  誠
  7. ────────────────────────────────────
  8.  
  9.  
  10. ━───────────────────────────────────
  11.  
  12.         FMPフォーマットとは
  13.  
  14. ────────────────────────────────────
  15.  
  16.   FMP フォーマットというのは、X68k の FM 音源 LSI(YM2151)の TL(Total
  17.  
  18. Level)レジスタに一定の間隔で直接流し込める状態になっている音声データの
  19.  
  20. フォーマットです。一定の間隔で音の波の変位を直接表しているデータの羅列で
  21.  
  22. あることに変わりはないので、PCM の一種と言えます。FM-PCM を縮めて FMP と
  23.  
  24. 呼ぶことにしました。これは私が S44PLAY.X のために勝手に付けた呼び方です。
  25.  
  26.  
  27.   X68k の FM 音源 LSI(YM2151)で、データのコンバートを行わずに直接再生
  28.  
  29. することができる PCM データのフォーマットは、FMP フォーマットだけです。
  30.  
  31. 実際には FMP フォーマットの PCM データを再生する場合にも各サンプリングデ
  32.  
  33. ータをどのチャンネルに流し込むかを再生時にプログラムでリアルタイムに決定
  34.  
  35. しなければならないので、“直接再生することができる”という表現にはやや語
  36.  
  37. 弊がありますが、FMP フォーマットの PCM データが他のフォーマットの PCM デ
  38.  
  39. ータよりも圧倒的に FM 音源で再生しやすいことは確かです。
  40.  
  41.  
  42.   一般的な PCM データ(拡張子が .S44 のファイルなど)を FM 音源で再生す
  43.  
  44. る場合はサンプリング周波数や PCM→FMP の変換を行わなければならないので再
  45.  
  46. 生の負荷が大きくなりますが、PCM データをあらかじめ特定のサンプリング周波
  47.  
  48. 数の FMP フォーマットに変換しておけば、データの変換を伴わずに再生できる
  49.  
  50. ので、遅い機種でも再生できるようになる場合があります。
  51.  
  52.  
  53.  
  54. ━───────────────────────────────────
  55.  
  56.         FMP フォーマットの概要
  57.  
  58. ────────────────────────────────────
  59.  
  60.   FMP フォーマットのデータは、FM 音源 LSI(YM2151)の TL レジスタに直接
  61.  
  62. 叩き込む数値を時間の順序で並べたものです。FMP フォーマットでは、1 つのチ
  63.  
  64. ャンネルの 1 つのサンプリングデータを 8 ビットで表現します。値の意味は次
  65.  
  66. の通りです。
  67.  
  68.  
  69.         FMP フォーマットのデータ
  70.  
  71.         $01~$7F        音の変位を示します。$01 が最大、$7F が最小(無音)。
  72.  
  73.         $FF             符号が反転することを示します。
  74.  
  75.  
  76.   なお、FMP フォーマットのデータに $00 がないのは、$00 は再生エンジンが
  77.  
  78. 内部で制御コードとして使用するためです。
  79.  
  80.  
  81.   FMP フォーマットのデータは、FM 音源の TL レジスタ(FM 音源 LSI のアド
  82.  
  83. レス $60~$7F)に直接書き込むことができるようになっています。
  84.  
  85.  
  86.                                 TL レジスタの配置
  87.  
  88.         FM 音源アドレス
  89.                            7   6   5   4   3   2   1   0
  90.                         ┌─┬─┬─┬─┬─┬─┬─┬─┐
  91.                 $60~$7F│×│            TL            │
  92.                         └─┴─┴─┴─┴─┴─┴─┴─┘
  93.  
  94.  
  95.   TL レジスタのビット 7 が未使用になっているところに注目して下さい。ここ
  96.  
  97. には何を書き込んでも無視されます。FMP フォーマットで $FF を符号の反転コ
  98.  
  99. ードにした理由は、下位 7 ビットを $7F にすることで使用中のチャンネルを無
  100.  
  101. 音にすると同時にビット 7 をセットしておくことで再生エンジンに符号の反転
  102.  
  103. を知らせて FM 音源のチャンネルを変更させるためです。現在の S44PLAY.X は
  104.  
  105. 音質を上げるために変位が + 側の音と - 側の音で使用する FM 音源のチャンネ
  106.  
  107. ルを変えてあるのです。
  108.  
  109.  
  110.   実際に出力される音の変位はほぼ 10^(-0.75/20*TL) に比例する値になります。
  111.  
  112. TL レジスタの設定値に対して音の変位が指数関数的に変化します。
  113.  
  114.  
  115.   ステレオの場合は、left0→right0→left1→right1→… の順序でデータを編
  116.  
  117. み込んでゆきます。ただ、ここで leftN と rightN を再生するタイミングがサ
  118.  
  119. ンプリング間隔の半分だけずれていることに注意して下さい。拡張子が .S44 の
  120.  
  121. ファイルでは leftN と rightN が同時に再生されますが、FMP フォーマットの
  122.  
  123. leftN と rightN は同時に再生されません。
  124.  
  125.  
  126.  
  127. ━───────────────────────────────────
  128.  
  129.         PCM→FMP変換
  130.  
  131. ────────────────────────────────────
  132.  
  133.   まず、絶対値の変換を考えます。前述のように、TL レジスタの設定値に対し
  134.  
  135. て音の変位は指数関数的に変化します。従って、線形な変位を表した PCM デー
  136.  
  137. タを TL レジスタに設定する値に変換するには対数計算を行わなければなりませ
  138.  
  139. ん。当然、いちいち対数計算を行っていては遅くなってしまうので、テーブルを
  140.  
  141. 使います。16 ビットの PCM データを変換するために 64KB のテーブルを用意し
  142.  
  143. ます。この 64KB のテーブルを作るときにも対数計算は行いません。S44PLAY.X
  144.  
  145. は内部に次のようなテーブルを持っていて、これを使って 64KB の PCM→FMP 変
  146.  
  147. 換テーブルを作ります。
  148.  
  149.  
  150.         対数テーブルを作るためのテーブル(preconv.s より抜粋)
  151.       ┌────────────────────────────────
  152.       │;(L(TL)-L(127))*32768のテーブル
  153.       │;       L(TL):=10^(-0.75/20*TL)
  154.       │        .align  4,$2048
  155.       │half_tl_table:
  156.       │        .dc.s   0.0249790331564598439725118169021/VOL   ;TL=126.5
  157.       │        .dc.s   0.0782918709331476020763667840649/VOL   ;TL=125.5
  158.       │        .dc.s   0.136412699922336602786363931527/VOL    ;TL=124.5
  159.       │        .dc.s   0.199775126370918425052560396896/VOL    ;TL=123.5
  160.       │        .dc.s   0.268851861085055585204731577729/VOL    ;TL=122.5
  161.       │        .dc.s   0.344158246055009330577173283454/VOL    ;TL=121.5
  162.       │        .dc.s   0.426256099126837360489754730109/VOL    ;TL=120.5
  163.       │        .dc.s   0.515757905403856993662565002971/VOL    ;TL=119.5
  164.       │        .dc.s   0.613331386647521673665138088852/VOL    ;TL=118.5
  165.       │        .dc.s   0.719704482767396026166953362516/VOL    ;TL=117.5
  166.       │        .dc.s   0.835670782564275638328249586056/VOL    ;TL=116.5
  167.       │        .dc.s   0.962095444242118369519663701653/VOL    ;TL=115.5
  168.       │        .dc.s   1.09992164985833884739083589277/VOL     ;TL=114.5
  169.       │        .dc.s   1.25017764186542639810460404596/VOL     ;TL=113.5
  170.       │        .dc.s   1.41398439423949693643416771827/VOL     ;TL=112.5
  171.       │        .dc.s   1.59256397542567932912798377748/VOL     ;TL=111.5
  172.       │        .dc.s   1.78724866549148627199992039775/VOL     ;TL=110.5
  173.       │        .dc.s   1.9994908955060339169251943125/VOL      ;TL=109.5
  174.       │        .dc.s   2.2308740832971310441830848046/VOL      ;TL=108.5
  175.       │        .dc.s   2.48312444642562093035569302004/VOL     ;TL=107.5
  176.       │        .dc.s   2.7581238805068177961204790857/VOL      ;TL=106.5
  177.       │        .dc.s   3.05792399895682477259486919328/VOL     ;TL=105.5
  178.       │        .dc.s   3.38476143890624676944056994051/VOL     ;TL=104.5
  179.       │        .dc.s   3.74107454746996202854224690479/VOL     ;TL=103.5
  180.       │        .dc.s   4.12952157285966282655455833564/VOL     ;TL=102.5
  181.       │        .dc.s   4.55300049605264658143806178966/VOL     ;TL=101.5
  182.       │        .dc.s   5.01467065096959003491609135695/VOL     ;TL=100.5
  183.       │        .dc.s   5.51797629445708127579538962277/VOL     ;TL=99.5
  184.       │        .dc.s   6.06667230191706194013552490339/VOL     ;TL=98.5
  185.       │        .dc.s   6.66485218028356717258122173868/VOL     ;TL=97.5
  186.       │        .dc.s   7.31697860733555307749532837661/VOL     ;TL=96.5
  187.       │        .dc.s   8.02791672518214930438951651899/VOL     ;TL=95.5
  188.       │        .dc.s   8.80297043630397886950532805413/VOL     ;TL=94.5
  189.       │        .dc.s   9.64792197293453999512298113455/VOL     ;TL=93.5
  190.       │        .dc.s   10.5690750349861618635689602561/VOL     ;TL=92.5
  191.       │        .dc.s   11.5733018183479152381211218609/VOL     ;TL=91.5
  192.       │        .dc.s   12.6680942844066978898191874225/VOL     ;TL=90.5
  193.       │        .dc.s   13.8616200532840539420906962171/VOL     ;TL=89.5
  194.       │        .dc.s   15.1627833377761835296985297871/VOL     ;TL=88.5
  195.       │        .dc.s   16.5812913725904012546005717612/VOL     ;TL=87.5
  196.       │        .dc.s   18.1277268344685641792656189175/VOL     ;TL=86.5
  197.       │        .dc.s   19.8136267934825696418567047588/VOL     ;TL=85.5
  198.       │        .dc.s   21.6515687845123606900904016501/VOL     ;TL=84.5
  199.       │        .dc.s   23.6552646410364842728276505249/VOL     ;TL=83.5
  200.       │        .dc.s   25.8396627912754194945564937378/VOL     ;TL=82.5
  201.       │        .dc.s   28.2210597798606648847674248799/VOL     ;TL=81.5
  202.       │        .dc.s   30.8172218470289422448988826375/VOL     ;TL=80.5
  203.       │        .dc.s   33.6475174723743143620728005205/VOL     ;TL=79.5
  204.       │        .dc.s   36.7330618719913062790308049138/VOL     ;TL=78.5
  205.       │        .dc.s   40.0968745270195300569385457903/VOL     ;TL=77.5
  206.       │        .dc.s   43.7640509188201426903516795659/VOL     ;TL=76.5
  207.       │        .dc.s   47.7619497520020175495666327316/VOL     ;TL=75.5
  208.       │        .dc.s   52.1203970620614939019679680501/VOL     ;TL=74.5
  209.       │        .dc.s   56.8719087303660091704604737974/VOL     ;TL=73.5
  210.       │        .dc.s   62.0519330665385781521145446469/VOL     ;TL=72.5
  211.       │        .dc.s   67.6991152680114780690122777743/VOL     ;TL=71.5
  212.       │        .dc.s   73.8555857297305391028174139176/VOL     ;TL=70.5
  213.       │        .dc.s   80.567274354923766077463525079/VOL      ;TL=69.5
  214.       │        .dc.s   87.884253211827079467601961444/VOL      ;TL=68.5
  215.       │        .dc.s   95.8611100927329297097983146142/VOL     ;TL=67.5
  216.       │        .dc.s   104.557355762272086666604989389/VOL     ;TL=66.5
  217.       │        .dc.s   114.037867933174996988874096728/VOL     ;TL=65.5
  218.       │        .dc.s   124.373375281761810792360717713/VOL     ;TL=64.5
  219.       │        .dc.s   135.640985114123682928968241141/VOL     ;TL=63.5
  220.       │        .dc.s   147.924758619610783711874040175/VOL     ;TL=62.5
  221.       │        .dc.s   161.316338003264118662012682439/VOL     ;TL=61.5
  222.       │        .dc.s   175.91563017586737016906831082/VOL      ;TL=60.5
  223.       │        .dc.s   191.831552102239013254268117846/VOL     ;TL=59.5
  224.       │        .dc.s   209.182843368381805915081516772/VOL     ;TL=58.5
  225.       │        .dc.s   228.098952029588185086788174853/VOL     ;TL=57.5
  226.       │        .dc.s   248.721000348307378065894196923/VOL     ;TL=56.5
  227.       │        .dc.s   271.202837626591836473127625685/VOL     ;TL=55.5
  228.       │        .dc.s   295.712187987703418455479657691/VOL     ;TL=54.5
  229.       │        .dc.s   322.431901669821093416624163188/VOL     ;TL=53.5
  230.       │        .dc.s   351.561319167036500802735824364/VOL     ;TL=52.5
  231.       │        .dc.s   383.317758394712735100073451992/VOL     ;TL=51.5
  232.       │        .dc.s   417.938135974096105603800981463/VOL     ;TL=50.5
  233.       │        .dc.s   455.680734731657619560311176809/VOL     ;TL=49.5
  234.       │        .dc.s   496.827130599465368014126536802/VOL     ;TL=48.5
  235.       │        .dc.s   541.684293292088871985834879115/VOL     ;TL=47.5
  236.       │        .dc.s   590.586876431983712271424749932/VOL     ;TL=46.5
  237.       │        .dc.s   643.899714208671470375279717095/VOL     ;TL=45.5
  238.       │        .dc.s   702.020543197860471085276864557/VOL     ;TL=44.5
  239.       │        .dc.s   765.382969646442293351473329926/VOL     ;TL=43.5
  240.       │        .dc.s   834.459704360579453503644510759/VOL     ;TL=42.5
  241.       │        .dc.s   909.766089330533198876086216484/VOL     ;TL=41.5
  242.       │        .dc.s   991.863942402361228788667663138/VOL     ;TL=40.5
  243.       │        .dc.s   1081.365748679380861961477936/VOL       ;TL=39.5
  244.       │        .dc.s   1178.93922992304554196405102188/VOL     ;TL=38.5
  245.       │        .dc.s   1285.31232604291989446586629555/VOL     ;TL=37.5
  246.       │        .dc.s   1401.27862583979950662716251909/VOL     ;TL=36.5
  247.       │        .dc.s   1527.70328751764223781857663468/VOL     ;TL=35.5
  248.       │        .dc.s   1665.5294931338627156897488258/VOL      ;TL=34.5
  249.       │        .dc.s   1815.78548514095026640351697899/VOL     ;TL=33.5
  250.       │        .dc.s   1979.5922375150208047330806513/VOL      ;TL=32.5
  251.       │        .dc.s   2158.17181870120319742689671051/VOL     ;TL=31.5
  252.       │        .dc.s   2352.85650876701014029883333078/VOL     ;TL=30.5
  253.       │        .dc.s   2565.09873878155778522410724553/VOL     ;TL=29.5
  254.       │        .dc.s   2796.48192657265491248199773763/VOL     ;TL=28.5
  255.       │        .dc.s   3048.73228970114479865460595307/VOL     ;TL=27.5
  256.       │        .dc.s   3323.73172378234166441939201873/VOL     ;TL=26.5
  257.       │        .dc.s   3623.53184223234864089378212631/VOL     ;TL=25.5
  258.       │        .dc.s   3950.36928218177063773948287354/VOL     ;TL=24.5
  259.       │        .dc.s   4306.68239074548589684115983782/VOL     ;TL=23.5
  260.       │        .dc.s   4695.12941613518669485347126867/VOL     ;TL=22.5
  261.       │        .dc.s   5118.60833932817044973697472269/VOL     ;TL=21.5
  262.       │        .dc.s   5580.27849424511390321500428998/VOL     ;TL=20.5
  263.       │        .dc.s   6083.5841377326051440943025558/VOL      ;TL=19.5
  264.       │        .dc.s   6632.28014519258580843443783642/VOL     ;TL=18.5
  265.       │        .dc.s   7230.46002355909104088013467171/VOL     ;TL=17.5
  266.       │        .dc.s   7882.58645061107694579424130964/VOL     ;TL=16.5
  267.       │        .dc.s   8593.52456845767317268842945202/VOL     ;TL=15.5
  268.       │        .dc.s   9368.57827957950273780424098716/VOL     ;TL=14.5
  269.       │        .dc.s   10213.5298162100638634218940676/VOL     ;TL=13.5
  270.       │        .dc.s   11134.6828782616857318678731891/VOL     ;TL=12.5
  271.       │        .dc.s   12138.9096616234391064200347939/VOL     ;TL=11.5
  272.       │        .dc.s   13233.7021276822217581181003555/VOL     ;TL=10.5
  273.       │        .dc.s   14427.2278965595778103896091502/VOL     ;TL=9.5
  274.       │        .dc.s   15728.3911810517073979974427202/VOL     ;TL=8.5
  275.       │        .dc.s   17146.8992158659251228994846942/VOL     ;TL=7.5
  276.       │        .dc.s   18693.3346777440880475645318505/VOL     ;TL=6.5
  277.       │        .dc.s   20379.2346367580935101556176918/VOL     ;TL=5.5
  278.       │        .dc.s   22217.1766277878845583893145831/VOL     ;TL=4.5
  279.       │        .dc.s   24220.8724843120081411265634579/VOL     ;TL=3.5
  280.       │        .dc.s   26405.2706345509433628554066708/VOL     ;TL=2.5
  281.       │        .dc.s   28786.6676231361887530663378129/VOL     ;TL=1.5
  282.       │                                                        ;0は使わない
  283.       │*       .dc.s   31382.8296903044661131977955705/VOL     ;TL=0.5
  284.       │        .dc.s   9999999999.0    ;番兵
  285.       │
  286.  
  287.  
  288.   なお、再生ボリュームの調整は 64KB の PCM→FMP 変換テーブルを生成する段
  289.  
  290. 階で行われるので、ボリュームの指定の有無は再生処理そのものの負荷を変化さ
  291.  
  292. せません。
  293.  
  294.  
  295.   さて、現在の S44PLAY.X は + 側の変位と - 側の変位を異なるチャンネルで
  296.  
  297. 再生することで音質を上げています。対数変換のテーブルを引くだけでは変位の
  298.  
  299. 絶対値が変換されるだけで、符号の変化を示すビット 7 が生成できていません。
  300.  
  301. FMP フォーマットのデータのビット 7 を生成するために、PCM→FMP 変換ルーチ
  302.  
  303. ンが PCM データの実際の符号の変化を監視して、符号が変わったところで FMP
  304.  
  305. フォーマットのデータを $FF にするという処理を行います。このとき、符号が
  306.  
  307. 変わる前後で絶対値が小さいほうを $FF にすることでノイズを減らします。
  308.  
  309.  
  310.   では、最も簡単な、周波数変換を伴わない場合の PCM→FMP 変換ルーチン(マ
  311.  
  312. クロ)を見て下さい。Atbl に PCM→FMP 変換テーブル(64KB)のベース位置
  313.  
  314. (先頭+32KB の位置)、Asrc に入力データのアドレス、Adst に出力バッファの
  315.  
  316. アドレス、Alim に入力データの末尾のアドレス+1 が設定された状態で、例えば
  317.  
  318.         PRECONV_EQUAL_LQ 0
  319.         PRECONV_EXIT_EQUAL_LQ 0
  320.  
  321. とすると、PCM データからモノラルの FMP フォーマットのデータを生成するル
  322.  
  323. ーチンになります(ステレオのときは Left と Right を分けて処理します)。
  324.  
  325.  
  326.         最も基本的な PCM→FMP 変換(preconv.mac,preconv.s より抜粋)
  327.       ┌────────────────────────────────
  328.       │;<Low Quality>
  329.       │;間隔が同じ→周波数が同じ
  330.       │;       side    0=Mono,1=StereoLeft,2=StereoRight
  331.       │;Ddat   dn
  332.       │;Rpre   dn/an
  333.       │;Dtmp   dn
  334.       │;Atbl   an
  335.       │;Asrc   an
  336.       │;Adst   an
  337.       │;Ajmp   an
  338.       │;Alim   dn/an
  339.       │PRECONV_EQUAL_LQ        .macro  side
  340.       │        move.w  preconv_pre_&side,Rpre
  341.       │        move.l  preconv_jmp_&side,Ajmp
  342.       │        move.l  Ajmp,Dtmp
  343.       │        beq     @spp
  344.       │        jmp     (Ajmp)
  345.       │
  346.       │@npp:   move.b  #$7F,(Adst)+
  347.       │        if side,<addq.l #1,Adst>
  348.       │        bra     @vpp
  349.       │@dpp:   move.b  (Atbl,Rpre.w),(Adst)+
  350.       │        if side,<addq.l #1,Adst>
  351.       │@vpp:   move.w  Ddat,Rpre
  352.       │        cmp.l   Alim,Asrc
  353.       │        bhs     @epp
  354.       │@spp:   GET_DATA_&side  Asrc,Ddat,Dtmp
  355.       │        bgt     @dpp
  356.       │        beq     @dpm
  357.       │        move.w  Ddat,Dtmp
  358.       │        add.w   Rpre,Dtmp
  359.       │        blt     @xmm
  360.       │@dpm:   move.b  (Atbl,Rpre.w),(Adst)+
  361.       │        if side,<addq.l #1,Adst>
  362.       │@vpm:   move.w  Ddat,Rpre
  363.       │        cmp.l   Alim,Asrc
  364.       │        bhs     @epm
  365.       │@spm:   GET_DATA_&side  Asrc,Ddat,Dtmp
  366.       │        bgt     @npp
  367.       │        beq     @npz
  368.       │@xmm:   st.b    (Adst)+
  369.       │        if side,<addq.l #1,Adst>
  370.       │        bra     @vmm
  371.       │@npz:   move.b  #$7F,(Adst)+
  372.       │        if side,<addq.l #1,Adst>
  373.       │        bra     @vpm
  374.       │
  375.       │@nmm:   move.b  #$7F,(Adst)+
  376.       │        if side,<addq.l #1,Adst>
  377.       │        bra     @vmm
  378.       │@dmm:   move.b  (Atbl,Rpre.w),(Adst)+
  379.       │        if side,<addq.l #1,Adst>
  380.       │@vmm:   move.w  Ddat,Rpre
  381.       │        cmp.l   Alim,Asrc
  382.       │        bhs     @emm
  383.       │@smm:   GET_DATA_&side  Asrc,Ddat,Dtmp
  384.       │        blt     @dmm
  385.       │        beq     @dmp
  386.       │        move.w  Ddat,Dtmp
  387.       │        add.w   Rpre,Dtmp
  388.       │        bgt     @xpp
  389.       │@dmp:   move.b  (Atbl,Rpre.w),(Adst)+
  390.       │        if side,<addq.l #1,Adst>
  391.       │@vmp:   move.w  Ddat,Rpre
  392.       │        cmp.l   Alim,Asrc
  393.       │        bhs     @emp
  394.       │@smp:   GET_DATA_&side  Asrc,Ddat,Dtmp
  395.       │        blt     @nmm
  396.       │        beq     @nmz
  397.       │@xpp:   st.b    (Adst)+
  398.       │        if side,<addq.l #1,Adst>
  399.       │        bra     @vpp
  400.       │@nmz:   move.b  #$7F,(Adst)+
  401.       │        if side,<addq.l #1,Adst>
  402.       │        bra     @vmp
  403.       │
  404.       │@epp:   lea.l   (@spp,pc),Ajmp
  405.       │        bra     @done
  406.       │
  407.       │@epm:   lea.l   (@spm,pc),Ajmp
  408.       │        bra     @done
  409.       │
  410.       │@emm:   lea.l   (@smm,pc),Ajmp
  411.       │        bra     @done
  412.       │
  413.       │@emp:   lea.l   (@smp,pc),Ajmp
  414.       │        bra     @done
  415.       │
  416.       │@done:
  417.       │        .endm
  418.       │PRECONV_EXIT_EQUAL_LQ   .macro  side
  419.       │        move.l  Ajmp,preconv_jmp_&side
  420.       │        move.w  Rpre,preconv_pre_&side
  421.       │        .endm
  422.  
  423.  
  424.   かなり読みにくいマクロになっていますが、これはソースをできるだけ短くす
  425.  
  426. るために入力データ(PCM データ)のフォーマットの違いをマクロのレベルで吸
  427.  
  428. 収するようになっているからです。例えば GET_DATA_0 というマクロはモノラル
  429.  
  430. の PCM データを 1 個レジスタに取り出してくるだけのマクロですが、エンディ
  431.  
  432. アンや入力データのチャンネル数の違いをここで吸収します。
  433.  
  434.  
  435.         マクロ GET_DATA_0 の定義の例(preconv.s より抜粋)
  436.       ┌────────────────────────────────
  437.       │;ステレオ→モノラル,16bit,big-endian
  438.       │GET_DATA_0      .macro  src,dat,tmp
  439.       │        move.w  (src)+,dat
  440.       │        add.w   (src)+,dat
  441.       │        bvc     @skip
  442.       │@over:
  443.       │        roxr.w  #1,dat                  ;常にvc
  444.       │        bra     @done
  445.       │@skip:
  446.       │        asr.w   #1,dat                  ;常にvc
  447.       │@done:
  448.       │        .endm
  449.       ┌────────────────────────────────
  450.       │;モノラル→モノラル,16bit,big-endian
  451.       │GET_DATA_0      .macro  src,dat,tmp
  452.       │        move.w  (src)+,dat              ;常にvc
  453.       │        .endm
  454.       ┌────────────────────────────────
  455.       │;ステレオ→モノラル,16bit,little-endian
  456.       │GET_DATA_0      .macro  src,dat,tmp
  457.       │        move.w  (src)+,dat
  458.       │        move.w  (src)+,tmp
  459.       │        rol.w   #8,dat
  460.       │        rol.w   #8,tmp
  461.       │        add.w   tmp,dat
  462.       │        bvc     @skip
  463.       │@over:
  464.       │        roxr.w  #1,dat                  ;常にvc
  465.       │        bra     @done
  466.       │@skip:
  467.       │        asr.w   #1,dat                  ;常にvc
  468.       │@done:
  469.       │        .endm
  470.       ┌────────────────────────────────
  471.       │;モノラル→モノラル,16bit,little-endian
  472.       │GET_DATA_0      .macro  src,dat,tmp
  473.       │        move.w  (src)+,dat
  474.       │        rol.w   #8,dat                  ;常にvc
  475.       │        .endm
  476.       │
  477.  
  478.  
  479.   マクロの全体は抜粋できるような規模ではないので、全体を把握したい人はソ
  480.  
  481. ースリスト(特に preconv.mac と preconv.s)をじっくり読んでみて下さい。
  482.  
  483.  
  484.  
  485. ━───────────────────────────────────
  486.  
  487.   PCM→FMP 変換は S44PLAY.X の基本的なところなのでちゃんと解説したかった
  488.  
  489. のですが、(最適化のせいもあって)マクロの塊が複雑すぎて解説になっていま
  490.  
  491. せんね。そもそもアセンブラの文法を知らなければチンプンカンプンでしょうし。
  492.  
  493. せめて S44PLAY.X のソースを覗くきっかけにしていただけるとよいのですが…。
  494.  
  495.  
  496.  
  497. (EOF)
  498.